﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{
    public class Observer : Entity, CommonAction.IActionListener
    {
        protected float mMoveSpeed = 20f; //0.05f;
        private IDK.Camera mCamera;
        private IDK.Vector3 mPosition;

        public bool Enable
        {
            get;
            set;
        }

        public Observer(IDK.Camera camera, IDK.Vector3 position)
        {
            Enable = true;
            mCamera = camera;
            mPosition = position;
        }

        public override void Invalidate()
        {
        }

        public void SetPosition(IDK.Vector3 pos)
        {
            mPosition = pos;
        }

        private enum MoveState
        {
            Boost,
            Forward,
            Backward,
            Leftward,
            Rightward,
        }

        private Set<MoveState> mMoveState = new Set<MoveState>();


        public void OnActivateAction(CommonAction.Action action)
        {
            if (Enable)
            {
                if (action is GameAction.PlayerMoveAction)
                {
                    GameAction.PlayerMoveAction plAct = (action as GameAction.PlayerMoveAction);
                    switch (plAct.States)
                    {
                        case GameAction.PlayerMoveAction.State.Forward:
                            mMoveState.Include(MoveState.Forward);
                            break;
                        case GameAction.PlayerMoveAction.State.TurnLeft:
                            mMoveState.Include(MoveState.Leftward);
                            break;
                        case GameAction.PlayerMoveAction.State.TurnRight:
                            mMoveState.Include(MoveState.Rightward);
                            break;
                        case GameAction.PlayerMoveAction.State.Backward:
                            mMoveState.Include(MoveState.Backward);
                            break;
                        case GameAction.PlayerMoveAction.State.Boost:
                            mMoveState.Include(MoveState.Boost);
                            break;
                    }
                }
            }
        }

        public void OnDeactivateAction(CommonAction.Action action)
        {
            if (Enable)
            {
                if (action is GameAction.PlayerMoveAction)
                {
                    GameAction.PlayerMoveAction plAct = (action as GameAction.PlayerMoveAction);
                    switch (plAct.States)
                    {
                        case GameAction.PlayerMoveAction.State.Forward:
                            mMoveState.Exclude(MoveState.Forward);
                            break;
                        case GameAction.PlayerMoveAction.State.TurnLeft:
                            mMoveState.Exclude(MoveState.Leftward);
                            break;
                        case GameAction.PlayerMoveAction.State.TurnRight:
                            mMoveState.Exclude(MoveState.Rightward);
                            break;
                        case GameAction.PlayerMoveAction.State.Backward:
                            mMoveState.Exclude(MoveState.Backward);
                            break;
                        case GameAction.PlayerMoveAction.State.Boost:
                            mMoveState.Exclude(MoveState.Boost);
                            break;
                    }
                }
            }
        }

        public override void OnUpdate(Events.ProcessSceneUpdate evnt)
        {

            if (Enable)
            {
                float moveSpeed = mMoveSpeed;

                foreach (MoveState state in mMoveState)
                {
                    switch (state)
                    {
                        //Sprint
                        case MoveState.Boost:
                            moveSpeed = mMoveSpeed * 2;
                            break;

                        //TurnLeft
                        case MoveState.Leftward:
                            mPosition.x += (moveSpeed * evnt.ElapsedTime);
                            break;

                        //TurnRight
                        case MoveState.Rightward:
                            mPosition.x += -(moveSpeed * evnt.ElapsedTime);
                            break;

                        //Forward
                        case MoveState.Forward:
                            mPosition.z += (moveSpeed * evnt.ElapsedTime);
                            break;

                        //Backward
                        case MoveState.Backward:
                            mPosition.z += -(moveSpeed * evnt.ElapsedTime);
                            break;
                    }
                }

                //Game.Log.Warn("camera update:" + dt.ToString());
                mCamera.LookAt(mPosition);
                mCamera.Update(evnt.ElapsedTime);
            }
        }
    }
}
